package br.indt.framework.ui.common;

import java.util.Vector;

import javax.microedition.lcdui.Font;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;

/**
 * Display a text (String) on screen.
 * 
 * @author Nokia Institute of Technology
 *
 */
public class Label extends Widget {
	public String text = null;
	public int number = 0;
	protected static final int LINE_GAP = 0;
	protected Vector textVector = null;
	protected int textColor = 0;
	protected Font font = null;
	protected int lines = 0;
	protected int maxLines = 0;
	protected boolean wrap = true;
	protected Icon icon = null;
	protected int anchor = Graphics.TOP | Graphics.LEFT;
//	protected LongPressedListener longPressedListener = null;
	protected Image numbers = null;
//	protected ObjectActionListener objectActionListener = null;

	protected int NUMBER_W = 7;
	protected int NUMBER_H = 9;

	public Label(int pNumber) {
		super("label_number");
		number = pNumber;
	//	numbers = ResourceManager.getImageResource("/numbers.png");
	}

	public Label(String name, String text) {
		this(name, text, true, 0, null);
		font = Font.getFont(Font.FACE_MONOSPACE, Font.STYLE_PLAIN, Font.SIZE_MEDIUM);
		setText(text);
	}

	public Label(String name, String text, boolean wrap, int maxLines, Icon icon) {
		super(name);

		this.maxLines = maxLines; 
		font = Font.getFont(Font.FACE_MONOSPACE, Font.STYLE_PLAIN, Font.SIZE_MEDIUM);
		this.wrap = wrap;
		setText(text);
		this.icon = icon;		
	}

	public int getNumber() {
		return number;
	}

	public void setNumber(int number) {
		this.number = number;
	}

	
	
	public void setIcon(Icon icon) {
		this.icon = icon;
	}

	/*
	 * Sample code:
	 * 		Label lblMsg = null;
	 * 		lblMsg = new Label("lblMsg", "Test align label.");
	 * 		lblMsg.setAlign(Graphics.HCENTER);
	 */
	public void setAlign(int align) {
		switch (align) {
		case Graphics.LEFT:
			setAnchor(Graphics.TOP | Graphics.LEFT);
			break;

		case Graphics.RIGHT:
			setAnchor(Graphics.TOP | Graphics.RIGHT);
			break;

		case Graphics.HCENTER:
			setAnchor(Graphics.TOP | Graphics.HCENTER);
			break;

		default:
			break;
		}
	}

	public void setAnchor(int anchor) {
		this.anchor = anchor;
	}

	public void setFont(Font font) {
		this.font = font;
		wrap();
	}

	public Font getFont() {
		return font;
	}

	public void setText(String text) {
		this.text = text;
		wrap();
	}

	public void setWidth(int width) {
		this.width = width;
		wrap();
	}

	private void calculateHeight() {
		height = topMargin + bottomMargin;
		height += (font.getHeight() + LINE_GAP) * lines;
	}

	public void setMargin(int left, int top, int right, int bottom) {
		super.setMargin(left, top, right, bottom);
		wrap();
	}

	private void wrap() {
		try {
			if (text != null) {
				if (wrap) {
					textVector = getWrappedTextVector(text, font, width - (leftMargin + rightMargin), 0);

				} else {
					textVector = getWrappedTextVector(text, font, width - (leftMargin + rightMargin), maxLines);
				}

			} else {
				if (textVector != null) {
					textVector.removeAllElements();

				} else {
					textVector = new Vector();
				}
			}

			if (textVector != null)	{
				lines = textVector.size();
			}

			calculateHeight();

		} catch (Exception e) {
			//Utils.logError("Label::wrap - " + e);
		}
	}

	public String getText() {
		return text;
	}

	public void setTextColor(int color) {
		this.textColor = color;
	}

	public int getTextColor() {
		return textColor;
	}

	public void paint(Graphics g, int x, int y, int maxWidth, int maxHeight) {
		try	{
			y += topMargin;
			x += leftMargin;

			
			g.setClip(x, y, maxWidth, height + 3);

			if (number > 0) {
				if (number < 9) {
					int _number = NUMBER_W*number;
					g.setClip(x, y, NUMBER_W, NUMBER_H);
					g.drawImage(numbers, x-_number, y, Graphics.TOP | Graphics.LEFT);

				} else {
					int units[] =null;// NCUtils.getDozenAndUnit(number);//todo

					for (int i = 0; i < units.length; i++) {
						int new_x = (x - 3)+i*7;
						g.setClip(new_x, y, NUMBER_W, NUMBER_H);
						int unit = NUMBER_W*units[i];
						g.drawImage(numbers, new_x-unit, y, Graphics.TOP | Graphics.LEFT);
					}
				}

			} else {
				g.setColor(textColor);
				g.setFont(font);

				if (lines > 0) {
					if (anchor == (Graphics.TOP | Graphics.HCENTER)) {
						x = ((x +maxWidth)/2)-leftMargin;
					}

					for (int i = 0; i < lines; i++) {
						if (icon != null) {
							g.drawString((String) textVector.elementAt(i), x + icon.getWidth() + 7, y, anchor);

						} else {
							g.drawString((String) textVector.elementAt(i), x, y, anchor);
						}

						y += font.getHeight() + LINE_GAP;
					}
				}

				if (icon != null) {
					icon.paint(g, x, y - 15, maxWidth, maxHeight);
				}
			}

		} catch (Exception e) {
			//empty
		}
	}

	private Vector getWrappedTextVector(String txt, Font font, int width, int maxLines) {
		Vector vt = new Vector();

		try {			
			int index = 0;
			int lastIndex = 0;
			String word = null;

			if (txt != null && txt.length() > 0) {
				txt = txt.trim();

				if (font.stringWidth(txt) < width) {
					vt.addElement(txt);
					return vt;

				} else {
					if (maxLines == 1) {
						vt.addElement(adjustTextToLabelWidth(txt, width));
						return vt;
					}
				}

				while (index > -1 && index < txt.length()) {
					index = txt.indexOf(" ", index + 1);

					if (index > -1 && index > lastIndex) {
						word = txt.substring(lastIndex, index).trim();
						lastIndex = index + 1;
						if (word.length() > 0) {
							addToVectorBasedOnWidth(word.trim(), vt, width, font);
						}
					}
				}

				if (lastIndex < txt.length() - 1) {
					word = txt.substring(lastIndex).trim();
					if (word.length() > 0) {
						addToVectorBasedOnWidth(word.trim(), vt, width, font);
					}
				}
			}

			String lastLine = "";
			String penultimateLine = "";

			if ((maxLines > 0) && (vt.size() > 0)) {				
				while (vt.size() >= maxLines) {
					lastLine = penultimateLine;
					penultimateLine = vt.elementAt(vt.size()-1).toString();
					vt.removeElementAt(vt.size()-1);					
				}

				lastLine = adjustTextToLabelWidth(penultimateLine + " " + lastLine, width);		
				vt.addElement(lastLine);
			}

		} catch (Exception e) {
		//	Utils.logError("Label::getWrappedTextVector - " + e);
		}

		if (vt.size() == 0) {
			return truncate(txt, font, width);
		}

		return vt;
	}

	private String adjustTextToLabelWidth(String givenText, int givenWidth) {
		String adjustedText = givenText;

		try	{
			if ((adjustedText != null) && (adjustedText.trim().length() > 0) && (givenWidth > 0)) {
				while (font.stringWidth(adjustedText) + font.stringWidth("...") >= givenWidth) {
					if (adjustedText.length() >= 0) {
						adjustedText = adjustedText.substring(0, adjustedText.length() - 1);
					}
				}				
				adjustedText += "...";
			}

		} catch (Exception e) {
		//	Utils.logError("Label::adjustTextToLabelWidth - " + e);
		}

		return adjustedText;
	}
	
	private void addToVectorBasedOnWidth (String word, Vector vt, int width, Font font) {
		if(font.stringWidth(word) > width) {
			//word wrap without space, use truncate method
		} else {
			if(vt.size() > 0) {
				int elementAt = vt.size() -1;
				StringBuffer sb = new StringBuffer((String)vt.elementAt(elementAt));
				sb.append(" ").append(word);

				if(font.stringWidth(sb.toString()) <= width) {
					vt.setElementAt(sb.toString(), elementAt);

				} else {
					vt.addElement(word);
				}

			} else {
				vt.addElement(word);
			}
		}
	}
	
	public Vector truncate(String text, Font font, int width) {
		Vector vt = null;
		try {
			if(text != null) {
				vt = new Vector();
				StringBuffer sb = new StringBuffer();

				for(int i=0; i<text.length(); i++) {
					sb.append(text.charAt(i));

					if(font.stringWidth(sb.toString()) > width) {
						sb.deleteCharAt(sb.length()-1);
						vt.addElement(sb.toString());
						sb.delete(0, sb.length());
						sb.append(text.charAt(i));
					}
				}
				vt.addElement(sb.toString());
			}

		} catch (Exception e) {
		//	Utils.logError("Err in truncate " + e);
		}
		return vt;
	}
	
	public int getActualWidth() {
		if(!wrap && textVector.size() > 0) {
			return font.stringWidth((String)textVector.elementAt(0)) + leftMargin + rightMargin;

		} else {
			int maxWidth = 0;
			int lineWidth = 0;

			for(int i = 0; i < lines; i++) {
				lineWidth = font.stringWidth((String) textVector.elementAt(i));

				if(lineWidth > maxWidth) {
					maxWidth = lineWidth;
				}
			}
			return maxWidth;
		}
	}
	
//	public void setLongPressedListener(LongPressedListener longPressedListener) {
//		this.longPressedListener = longPressedListener;
//	}
	
	public void pressFire() {
		click(0,0);
	}
	
	public void click(int x, int y) {
		
//		if(objectActionListener != null){
//			objectActionListener.objetcClicked(x,y,this);
//		}
	}
	
	public void longPressed(int x, int y) {
//		if(longPressedListener != null){
//			longPressedListener.longPressed(null, x, y);
//		}

		setPressedDownState(false);
		//Utils.logInfo("Long pressed MemberItemFullTouch");
	}
//	public void setObjectActionListener(ObjectActionListener objectActionListener) {
//		this.objectActionListener = objectActionListener;
//	}
}
